#pragma once
#include "guid.h"
#include <vector>
#include "GtdTime.h"
#include "GtdTaskLoopPolicy.h"
#include "xmlNode.h"


class GtdProject;
class GtdContext;
class GtdTaskEntry;
class GtdTaskItem;
class GtdDOM;

class GtdDOMItem
{
public:
	GtdDOMItem(GtdDOM* pDom);
	GtdDOM* getDom()const{ return mpDom; }

	void saveToXMLNode(xmlNode& node);
	bool readFromXMLNode(xmlNode& node);	
	
	CString msName;
	CGuid m_id;
	virtual ~GtdDOMItem(){}


	virtual GtdProject* toProject(){ return NULL; }
	virtual GtdContext* toContext(){ return NULL; }
	virtual GtdTaskEntry* toTaskEntry(){ return NULL; }
	virtual GtdTaskItem* toTaskItem(){ return NULL; }
protected:
	virtual void toXMLNode(xmlNode& node)=0;
	virtual void fromXMLNode(xmlNode& node)=0;
	//GtdDOMItem();
	GtdDOM * mpDom;
};


#define DOMITEM_CONSTRUCT(T, TP) T(GtdDOM* pDom):TP(pDom){}

//



class GtdProject : public GtdDOMItem
{
public:
	DOMITEM_CONSTRUCT(GtdProject,GtdDOMItem)
	CGuid mParent; //parent project

	GtdProject* toProject(){ return this; } 

	GtdProject* GetParent()const;
	//GuidList mChildPrj;
	//GuidList mEntryList;	
	virtual void toXMLNode(xmlNode& node);
	virtual void fromXMLNode(xmlNode& node);

};

class GtdContext: public GtdDOMItem
{
public:	
	DOMITEM_CONSTRUCT(GtdContext,GtdDOMItem)
	GtdContext* toContext(){ return this; }
	virtual void toXMLNode(xmlNode& node){}
	virtual void fromXMLNode(xmlNode& node){}

};




////
class TaskEntryCheckItem : public GtdDOMItem
{
public:	
	DOMITEM_CONSTRUCT(TaskEntryCheckItem,GtdDOMItem)
	virtual void toXMLNode(xmlNode& node){}
	virtual void fromXMLNode(xmlNode& node){}	
};


class GtdTaskEntry: public GtdDOMItem
{
public:
	DOMITEM_CONSTRUCT(GtdTaskEntry,GtdDOMItem)

	bool hasContext(const CGuid& id)const;
	bool IsContexted()const;

	GuidList mCtxlist;
	CGuid mPrj;
	GtdTaskLoopPolicy mLoopPolicy;

	virtual void toXMLNode(xmlNode& node);
	virtual void fromXMLNode(xmlNode& node);

	GtdTaskEntry* toTaskEntry(){ return this; }
public:	
	void AddCheckItem(TaskEntryCheckItem* pItem){ mCheckList.push_back(pItem); }
	void RemoveCheckItem(int idx){ mCheckList.erase(mCheckList.begin()+idx); }
public:
	typedef std::vector<TaskEntryCheckItem*> CheckItemList;
	CheckItemList mCheckList; //steps of this task
	CTime mtFrom;
	CTime mtTo;
protected:
	
};

//task item is copy of task entry if the task entry is loop task
class TaskItemCheckItem : public GtdDOMItem
{
public:
	DOMITEM_CONSTRUCT(TaskItemCheckItem,GtdDOMItem)
	CGuid entryCheckItem; //entry check item ref to
	virtual void toXMLNode(xmlNode& node);
	virtual void fromXMLNode(xmlNode& node);	
	bool m_bDone;
};
class GtdTaskItem: public GtdDOMItem
{
public:	
	DOMITEM_CONSTRUCT(GtdTaskItem,GtdDOMItem)
	CGuid mTaskEntry; //task 
	virtual void toXMLNode(xmlNode& node);
	virtual void fromXMLNode(xmlNode& node);
	GtdTaskItem* toTaskItem(){ return this; } 
	GtdTaskEntry* GetEntry()const;

	void AddCheckItem(TaskItemCheckItem* pItem){ mCheckList.push_back(pItem); }
	void RemoveCheckItem(int idx){ mCheckList.erase(mCheckList.begin()+idx); }
	int GetCheckCount()const{ return (int)mCheckList.size(); }
	TaskItemCheckItem* GetCheckItem(int idx)const{ return mCheckList.at(idx); }
	bool m_bDone;
protected:
	typedef std::vector<TaskItemCheckItem*> CheckItemList;
	CheckItemList mCheckList; 
	CTime mtFrom;
	CTime mtTo;
};

